﻿using Microsoft.WindowsAPICodePack.Dialogs;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Windows.Forms;
//using Microsoft.WindowsAPICodePack.Dialogs;

namespace TestPictrueGenerator
{

    public partial class Form1 : Form
    {
        Color colorGradientStart;
        Color colorGradientStop;

        int resX;
        int resY;
        int keepY;
        string outpuFolder;
        string stringGenTime;
        string imageFormat;

        int groupSelectMode = 0;

        #region TabPage Timming Golbal Variables

        DPI_Timming dpitm;
        DSI_Timming dsitm;

        #endregion

        //IDictionary<string, Bitmap> outputBuffer = new Dictionary<string, Bitmap>();
        List<PrepareImageData> outputBuffer = new List<PrepareImageData>();


        public static Image GetThumbnail(Image image, int width, int height)
        {
            Bitmap bmp = new Bitmap(width, height);
            //从Bitmap创建一个System.Drawing.Graphics
            System.Drawing.Graphics gr = System.Drawing.Graphics.FromImage(bmp);
            //设置 
            //gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            //下面这个也设成高质量
            //gr.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
            //下面这个设成High
            gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            //把原始图像绘制成上面所设置宽高的缩小图
            System.Drawing.Rectangle rectDestination = new Rectangle(0, 0, width, height);

            gr.DrawImage(image, rectDestination, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel);
            return bmp;
        }


        void gradientEnable()
        {
            if (checkBox_Gradient.Checked == true)
            {
                radioButton_GD_LR.Enabled = true;
                radioButton_GD_RL.Enabled = true;
                radioButton_GD_UD.Enabled = true;
                radioButton_GD_DU.Enabled = true;
                radioButton_GD_LU_RD.Enabled = true;
                radioButton_GD_RU_LD.Enabled = true;
                radioButton_GD_LD_RU.Enabled = true;
                radioButton_GD_RD_LU.Enabled = true;
            }
            else
            {
                radioButton_GD_LR.Enabled = false;
                radioButton_GD_RL.Enabled = false;
                radioButton_GD_UD.Enabled = false;
                radioButton_GD_DU.Enabled = false;
                radioButton_GD_LU_RD.Enabled = false;
                radioButton_GD_RU_LD.Enabled = false;
                radioButton_GD_LD_RU.Enabled = false;
                radioButton_GD_RD_LU.Enabled = false;
            }
        }

        void getFlickerPatternColor(out Color co, out Color ce)
        {
            int OR = Convert.ToInt32(Math.Round(numericUpDown_OR.Value, 0));
            int OG = Convert.ToInt32(Math.Round(numericUpDown_OG.Value, 0));
            int OB = Convert.ToInt32(Math.Round(numericUpDown_OB.Value, 0));
            int ER = Convert.ToInt32(Math.Round(numericUpDown_ER.Value, 0));
            int EG = Convert.ToInt32(Math.Round(numericUpDown_EG.Value, 0));
            int EB = Convert.ToInt32(Math.Round(numericUpDown_EB.Value, 0));

             co = Color.FromArgb(OR, OG, OB);
             ce = Color.FromArgb(ER, EG, EB);
        }

        void ChangeFlickerPattern()
        {
            int OR = Convert.ToInt32(Math.Round(numericUpDown_OR.Value, 0));
            int OG = Convert.ToInt32(Math.Round(numericUpDown_OG.Value, 0));
            int OB = Convert.ToInt32(Math.Round(numericUpDown_OB.Value, 0));
            int ER = Convert.ToInt32(Math.Round(numericUpDown_ER.Value, 0));
            int EG = Convert.ToInt32(Math.Round(numericUpDown_EG.Value, 0));
            int EB = Convert.ToInt32(Math.Round(numericUpDown_EB.Value, 0));

            Color co = Color.FromArgb(OR, OG, OB);
            Color ce = Color.FromArgb(ER, EG, EB);
            Console.WriteLine(co.ToString() + ce.ToString());

            Graphics go1 = pictureBox_O1.CreateGraphics();
            Graphics go2 = pictureBox_O2.CreateGraphics();
            Graphics ge1 = pictureBox_E1.CreateGraphics();
            Graphics ge2 = pictureBox_E2.CreateGraphics();

            go1.Clear(co);
            go2.Clear(co);
            ge1.Clear(ce);
            ge2.Clear(ce);

            go1.Dispose();
            go2.Dispose();
            ge1.Dispose();
            ge2.Dispose();

            pictureBox_O1.BackColor = co;
            pictureBox_O2.BackColor = co;
            pictureBox_E1.BackColor = ce;
            pictureBox_E2.BackColor = ce;

            /*Bitmap bmo1 = new Bitmap(pictureBox_O1.Image);
            Bitmap bme1 = new Bitmap(pictureBox_E1.Image);
            Bitmap bmo2 = new Bitmap(pictureBox_O2.Image);
            Bitmap bme2 = new Bitmap(pictureBox_E2.Image);*/

            /*Graphics go1 = Graphics.FromImage(bmo1);
            Graphics ge1 = Graphics.FromImage(bme1);
            Graphics go2 = Graphics.FromImage(bmo2);
            Graphics ge2 = Graphics.FromImage(bme2);*/

            /*go1.Clear(co);
            ge1.Clear(ce);
            go2.Clear(co);
            ge2.Clear(ce);*/


            /*pictureBox_O1.Image = (Image)go;
            Image imgo2 = pictureBox_O2.Image;
            Image imge1 = pictureBox_E1.Image;
            Image imge2 = pictureBox_E2.Image;*/


            /*go.DrawImage(imgo1, 0, 0, 32, 32);
            go.DrawImage(imgo2, 0, 0, 32, 32);
            go.DrawImage(imge1, 0, 0, 32, 32);
            go.DrawImage(imge2, 0, 0, 32, 32);*/
        }

        public Bitmap Conver32bppTo24bpp(Bitmap in32bppImage)
        {
            var bmp = new Bitmap(in32bppImage.Width, in32bppImage.Height, PixelFormat.Format24bppRgb);
            var gr = Graphics.FromImage(bmp);
            gr.DrawImage(in32bppImage, new Rectangle(0, 0, in32bppImage.Width, in32bppImage.Height));
            return bmp;
        }

        /// <summary>
        /// 把Bitmap保存到文件
        /// </summary>
        /// <param name="img">Bitmap对象</param>
        /// <param name="fp">文件路径</param>
        /// <param name="fn">文件名</param>
        /// <param name="ext">扩展名</param>
        void saveImage(Bitmap img, string fp, string subf, string fn, string ext)
        {
            string fullPath = Path.Combine(fp, subf);
            Directory.CreateDirectory(fullPath);

            string fullName = Path.Combine(fullPath, fn + ext);
            Console.WriteLine("full output file name: " + fullName);

            if (System.IO.File.Exists(fullName))
            {
                System.IO.File.Delete(fullName);
            }

            if(ext.Equals(".bmp"))
                Conver32bppTo24bpp(img).Save(fullName, System.Drawing.Imaging.ImageFormat.Bmp);

            if (ext.Equals(".jpg"))
                Conver32bppTo24bpp(img).Save(fullName, System.Drawing.Imaging.ImageFormat.Jpeg);

            if (ext.Equals(".png"))
                Conver32bppTo24bpp(img).Save(fullName, System.Drawing.Imaging.ImageFormat.Png);

        }

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            #region TabPage Image Gen

            LCD_Code lcd_D = new LCD_Code();
            lcd_D.code = "D";
            lcd_D.wh.w = 240;
            lcd_D.wh.h = 320;
            comboBox_LCD_Resolution_YES_LCD.Items.Add(lcd_D);

            LCD_Code lcd_H = new LCD_Code();
            lcd_H.code = "H";
            lcd_H.wh.w = 320;
            lcd_H.wh.h = 480;
            comboBox_LCD_Resolution_YES_LCD.Items.Add(lcd_H);

            LCD_Code lcd_I = new LCD_Code();
            lcd_I.code = "I";
            lcd_I.wh.w = 480;
            lcd_I.wh.h = 272;
            comboBox_LCD_Resolution_YES_LCD.Items.Add(lcd_I);

            LCD_Code lcd_R = new LCD_Code();
            lcd_R.code = "R";
            lcd_R.wh.w = 800;
            lcd_R.wh.h = 480;
            comboBox_LCD_Resolution_YES_LCD.Items.Add(lcd_R);

            LCD_Code lcd_T = new LCD_Code();
            lcd_T.code = "T";
            lcd_T.wh.w = 1024;
            lcd_T.wh.h = 600;
            comboBox_LCD_Resolution_YES_LCD.Items.Add(lcd_T);

            LCD_Code lcd_X = new LCD_Code();
            lcd_X.code = "X";
            lcd_X.wh.w = 720;
            lcd_X.wh.h = 1280;
            comboBox_LCD_Resolution_YES_LCD.Items.Add(lcd_X);

            LCD_Code lcd_W = new LCD_Code();
            lcd_W.code = "W";
            lcd_W.wh.w = 800;
            lcd_W.wh.h = 1280;
            comboBox_LCD_Resolution_YES_LCD.Items.Add(lcd_W);

            comboBox_LCD_Resolution_YES_LCD.SelectedIndex = 0;

            resX = Convert.ToInt32(Math.Round(numericUpDown_ResX.Value, 0));
            resY = Convert.ToInt32(Math.Round(numericUpDown_ResY.Value, 0));
            keepY = Convert.ToInt32(Math.Round(numericUpDown_CutKeep.Value, 0));

            ChangeFlickerPattern();

            gradientEnable();

            colorGradientStart = Color.White;
            pictureBox_GradientStartColor.BackColor = colorGradientStart;

            colorGradientStop = Color.Black;
            pictureBox_GradientStopColor.BackColor = colorGradientStop;
            #endregion

            #region TabPage Timming
            UInt16 hsw = Convert.ToUInt16(Math.Round(numericUpDown_HSW.Value, 0));
            UInt16 hbp = Convert.ToUInt16(Math.Round(numericUpDown_HBP.Value, 0));
            UInt16 hact = Convert.ToUInt16(Math.Round(numericUpDown_HACT.Value, 0));
            UInt16 hfp = Convert.ToUInt16(Math.Round(numericUpDown_HFP.Value, 0));
            UInt16 vsw = Convert.ToUInt16(Math.Round(numericUpDown_VSW.Value, 0));
            UInt16 vbp = Convert.ToUInt16(Math.Round(numericUpDown_VBP.Value, 0));
            UInt16 vact = Convert.ToUInt16(Math.Round(numericUpDown_VACT.Value, 0));
            UInt16 vfp = Convert.ToUInt16(Math.Round(numericUpDown_VFP.Value, 0));

            dpitm = new DPI_Timming(hsw, hbp, hact, hfp, vsw, vbp, vact, vfp);

            comboBox_DsiColorFormat.SelectedIndex = 0;

            comboBox_PolHs.SelectedIndex = 0;
            comboBox_PolVs.SelectedIndex = 0;
            comboBox_PolDe.SelectedIndex = 0;
            comboBox_PolClk.SelectedIndex = 0;
            #endregion
        }

        /// <summary>
        /// 主要工作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_Generate_Click(object sender, EventArgs e)
        {
            outputBuffer.Clear();

            #region 选择输出文件夹
            CommonOpenFileDialog dialog = new CommonOpenFileDialog();
            if(string.IsNullOrEmpty( Properties.Settings.Default.lastOutputFolder) == true)
            {
                dialog.InitialDirectory = "C:\\Users";
            } else
            {
                dialog.InitialDirectory = Properties.Settings.Default.lastOutputFolder;
            }
            
            dialog.IsFolderPicker = true;


            if (dialog.ShowDialog() == CommonFileDialogResult.Ok)
            {
                outpuFolder = dialog.FileName;

                Properties.Settings.Default.lastOutputFolder = outpuFolder;
                Properties.Settings.Default.Save();
            }
            else
            {
                return;
            }

            #endregion

            #region 获取时间, 产生时间字符串作为文件名前缀
            stringGenTime = DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss");
            Console.WriteLine("file name prefix: " + stringGenTime);
            #endregion

            #region 文件扩展名
            //string imageFormat;

            if(radioButton_BMP.Checked == true)
            {
                imageFormat = ".bmp";
            } else if(radioButton_JPG.Checked == true)
            {
                imageFormat = ".jpg";
            } else
            {
                imageFormat = ".png";
            }
            Console.WriteLine("output file format = " + imageFormat);
            #endregion

            #region 获取分辨率信息
            Console.WriteLine(string.Format("output picture size: ({0},{1}) cut-keep:{2}", resX, resY, keepY));
            #endregion

            BitmapGenerator bg = new BitmapGenerator(resX, resY);

            #region 根据checkbox填充outputbuffer

            #region YES-LCD Standard Test Images

            #region 9pics for assemble

            #region 1 Black and 1line Frame
            if (checkBox_Frame.Checked)
            {
                Console.WriteLine("checkBox_Frame.Checked");
                var imagedata = new Bitmap(resX, resY);

                int w = Convert.ToInt32(Math.Round(numericUpDown_FrameWidth.Value, 0));

                if (checkBox_FrameIsCircle.Checked == true)
                {
                    imagedata = bg.createFrameCircleImage(w);
                } else
                {
                    imagedata = bg.createFrameImage(w);
                }
                outputBuffer.Add(new PrepareImageData(textBox_DetailModeSubfolder.Text, "1", imagedata));
            }
            #endregion

            #region 2 White
            if (checkBox_White.Checked)
            {
                var imagedata = bg.createColorImage(Color.White);
                outputBuffer.Add(new PrepareImageData(textBox_DetailModeSubfolder.Text, "2", imagedata));
            }
            #endregion

            #region 3 Red
            if (checkBox_Red.Checked)
            {
                var imagedata = bg.createColorImage(Color.Red);
                outputBuffer.Add(new PrepareImageData(textBox_DetailModeSubfolder.Text, "3", imagedata));
            }
            #endregion

            #region 4 Green
            if (checkBox_Green.Checked)
            {
                Color pureGreen = Color.FromArgb(255, 0, 255, 0);
                var imagedata = bg.createColorImage(pureGreen);
                outputBuffer.Add(new PrepareImageData(textBox_DetailModeSubfolder.Text, "4", imagedata));
            }
            #endregion

            #region 5 Blue
            if (checkBox_Blue.Checked)
            {
                var imagedata = bg.createColorImage(Color.Blue);
                outputBuffer.Add(new PrepareImageData(textBox_DetailModeSubfolder.Text, "5", imagedata));
            }
            #endregion

            #region 6 Pure Black
            if (checkBox_Black.Checked)
            {
                var imagedata = bg.createColorImage(Color.Black);
                outputBuffer.Add(new PrepareImageData(textBox_DetailModeSubfolder.Text, "6", imagedata));
            }
            #endregion

            #region 7 Gray Gradient and CrossTalk
            if (checkBox_Gray.Checked)
            {
                Bitmap imagedata = new Bitmap(resX, resY);

                var sourcegra = Graphics.FromImage(imagedata);//存入画布
                sourcegra.Clear(Color.White);

                System.Drawing.Drawing2D.LinearGradientBrush lgb = new System.Drawing.Drawing2D.LinearGradientBrush(new Point(resX, resY), new Point(-1, -1), colorGradientStart, colorGradientStop);
                sourcegra.FillRectangle(lgb, 0, 0, resX, resY);

                SolidBrush sb = new SolidBrush(Color.White);
                sourcegra.FillRectangle(sb, new Rectangle(resX / 6, resY / 4, 2*resX / 3, resY / 2));

                outputBuffer.Add(new PrepareImageData(textBox_DetailModeSubfolder.Text, "7", imagedata));
            }
            #endregion

            #region 8 Color Bar
            if (checkBox_ColorBar.Checked)
            {
                Bitmap imagedata = bg.createColorBar();
                outputBuffer.Add(new PrepareImageData(textBox_DetailModeSubfolder.Text, "8", imagedata));
            }
            #endregion

            #region 9 Pic
            if (checkBox_Pic.Checked)
            {
                Bitmap original = (Bitmap)Properties.Resources._9;
                Bitmap imagedata = new Bitmap(original, new Size(resX, resY));
                outputBuffer.Add(new PrepareImageData(textBox_DetailModeSubfolder.Text, "9", imagedata));
            }
            #endregion

            #endregion 9pics for assemble

            #region 4pics Simple Mode Folder

            #region 1 Black and 1line Frame
            if (checkBox_SimpleFrame.Checked)
            {
                Console.WriteLine("checkBox_Frame.Checked");
                var imagedata = new Bitmap(resX, resY);

                int w = Convert.ToInt32(Math.Round(numericUpDown_FrameWidth.Value, 0));

                if (checkBox_FrameIsCircle.Checked == true)
                {
                    imagedata = bg.createFrameCircleImage(w);
                }
                else
                {
                    imagedata = bg.createFrameImage(w);
                }
                outputBuffer.Add(new PrepareImageData(textBox_SimpleModeSubfolder.Text, "1", imagedata));
            }
            #endregion


            #region 2 White
            if (checkBox_SimpleWhite.Checked)
            {
                var imagedata = bg.createColorImage(Color.White);
                outputBuffer.Add(new PrepareImageData(textBox_SimpleModeSubfolder.Text, "2", imagedata));
            }
            #endregion


            #region 3 Color Bar
            if (checkBox_SimpleColorBar.Checked)
            {
                Bitmap imagedata = bg.createColorBar();
                outputBuffer.Add(new PrepareImageData(textBox_SimpleModeSubfolder.Text, "3", imagedata));
            }
            #endregion


            #region 4 Gray Gradient and CrossTalk
            if (checkBox_SimpleGray.Checked)
            {
                Bitmap imagedata = new Bitmap(resX, resY);

                var sourcegra = Graphics.FromImage(imagedata);//存入画布
                sourcegra.Clear(Color.White);

                System.Drawing.Drawing2D.LinearGradientBrush lgb = new System.Drawing.Drawing2D.LinearGradientBrush(new Point(resX, resY), new Point(-1, -1), colorGradientStart, colorGradientStop);
                sourcegra.FillRectangle(lgb, 0, 0, resX, resY);

                SolidBrush sb = new SolidBrush(Color.White);
                sourcegra.FillRectangle(sb, new Rectangle(resX / 6, resY / 4, 2 * resX / 3, resY / 2));

                outputBuffer.Add(new PrepareImageData(textBox_SimpleModeSubfolder.Text, "4", imagedata));
            }
            #endregion


            #endregion Simple Mode Folder

            #region Yes-Lcd Logo
            if (checkBox_All_RGB_Yes.Checked)
            {
                Bitmap original = (Bitmap)Properties.Resources.Yes_Lcd;
                Bitmap imagedata = new Bitmap(original, new Size(resX, resY));
                Bitmap outputData = new Bitmap(original, new Size(resX, resY));
                Console.WriteLine(DateTime.Now);

                #region 准备原始图片像素数组
                List<Pixel> image_pixs = new List<Pixel>();
                for(int y = 0; y < imagedata.Height; y++)
                {
                    for (int x = 0; x < imagedata.Width; x++)
                    {
                        image_pixs.Add(new Pixel(x, y, Pixel.C2I( imagedata.GetPixel(x, y)) ));         
                    }
                }
                Console.WriteLine("image_pixs count: " + image_pixs.Count);
                Console.WriteLine(DateTime.Now);
                #endregion

                #region 准备全色彩数组
                List<int> allRgb = new List<int>();
                for(int i = 0; i < image_pixs.Count; i++)
                {
                    allRgb.Add(i * ( (4096*4096) / image_pixs.Count) );
                }
                Console.WriteLine(DateTime.Now);
                #endregion

                #region 从原始图片像素数组随机拿一个, 到全色数组里面找相近的, 填到输出bitmap

                #region 方法1
                /*Random rd = new Random((int) DateTime.Now.Ticks );
                for (int i = 0; i < image_pixs.Count; i++)
                {
                    int index = rd.Next(0, image_pixs.Count);
                    //Console.WriteLine(index);

                    Pixel p = (Pixel)image_pixs[index];

                    // 算法不佳
                    int i2 = 0;
                    for( ; i2 < allRgb.Count; i2++)
                    {
                        if( p.color < (int)allRgb[i2])
                        {
                            //Console.WriteLine(i2.ToString() + "# best match color" + p.color.ToString() + " " + (int)allRgb[i2]);
                            break;
                        }
                    }

                    //Console.WriteLine("i2:" + i2.ToString() + " allRgb count: " + allRgb.Count);
                    if (i2 == allRgb.Count)
                    {
                        i2 = allRgb.Count - 1;
                    }
                    int bestMatchColor = (int)(allRgb[i2]);
                    outputData.SetPixel(p.x, p.y, Pixel.I2C(bestMatchColor));


                    //image_pixs
                    image_pixs.RemoveAt(index);
                    //allRgb
                    allRgb.RemoveAt(i2);

                    
                }*/
                #endregion 方法1

                #region 方法2
                Random rd1 = new Random((int)DateTime.Now.Ticks);

                List<int> pixelIndex = new List<int>();
                for(int i =0; i < imagedata.Width * imagedata.Height; i++)
                {
                    pixelIndex.Add(i);
                }

                List<int> randomrizedPixelIndex = new List<int>();
                foreach (var item in pixelIndex)
                {
                    int c = rd1.Next(0, randomrizedPixelIndex.Count);
                    randomrizedPixelIndex.Insert(c, item);
                }

                List<int> colorSpace = new List<int>();
                int colorInterval = 4096 * 4096 / (imagedata.Width * imagedata.Height);
                for (int i = 0; i < imagedata.Width * imagedata.Height; i++)
                {
                    colorSpace.Add(i * colorInterval);
                }

                foreach (int i in randomrizedPixelIndex)
                {
                    //Console.WriteLine(pixelIndexInOriginImage);

                    //randomrizedPixelIndex[i]
                }

                #endregion 方法2


                Console.WriteLine(DateTime.Now);
                #endregion


                outputBuffer.Add(new PrepareImageData("", "Yes_Lcd_Logo_ALLRGB", outputData));
            }

            #endregion

            #endregion

            #region 常用

            #region Scaler
            if (checkBox_Scale.Checked)
            {
                Console.WriteLine("checkBox_Scale.Checked");
                var imagedata = bg.createScaleImage();
                outputBuffer.Add(new PrepareImageData("", "Scale", imagedata));
            }
            #endregion

            #region 边框斜三角
            if (checkBox_Frame_Triangle.Checked)
            {
                Console.WriteLine("checkBox_Frame_Triangle.Checked");
                var imagedata = bg.createFrameTriangleImage();
                outputBuffer.Add(new PrepareImageData("", "Frame_Triangle", imagedata));
            }
            #endregion

            #region Chess 棋盘格
            if (checkBox_Chess.Checked)
            {
                Console.WriteLine("checkBox_Chess.Checked");
                int gs = Convert.ToInt32(Math.Round(numericUpDown_Chess.Value, 0));
                var imagedata = bg.createChessImage(gs);
                outputBuffer.Add(new PrepareImageData("", "Chess", imagedata));
            }
            #endregion


            #region 间隔横竖线

            if (checkBox_HLINE.Checked)
            {
                Console.WriteLine("checkBox_HLINE.Checked");
                List<Color> ca = new List<Color>();
                Bitmap imagedata;

                int line_width = Convert.ToInt32(Math.Round(numericUpDown_HVLINE_WIDTH.Value, 0));

                ca.Clear();
                ca.Add(Color.White);
                ca.Add(Color.White);
                ca.Add(Color.Black);
                ca.Add(Color.Black);
                imagedata = bg.create_image_four_quadrant_square_texture(ca, line_width);
                outputBuffer.Add(new PrepareImageData("", "HLine1", imagedata));

                ca.Clear();
                ca.Add(Color.Black);
                ca.Add(Color.Black);
                ca.Add(Color.White);
                ca.Add(Color.White);
                imagedata = bg.create_image_four_quadrant_square_texture(ca, line_width);
                outputBuffer.Add(new PrepareImageData("", "HLine2", imagedata));
            }

            if (checkBox_VLINE.Checked)
            {
                Console.WriteLine("checkBox_VLINE.Checked");
                List<Color> ca = new List<Color>();
                Bitmap imagedata;

                int line_width = Convert.ToInt32(Math.Round(numericUpDown_HVLINE_WIDTH.Value, 0));

                ca.Clear();
                ca.Add(Color.White);
                ca.Add(Color.Black);
                ca.Add(Color.White);
                ca.Add(Color.Black);
                imagedata = bg.create_image_four_quadrant_square_texture(ca, line_width);
                outputBuffer.Add(new PrepareImageData("", "VLine1", imagedata));

                ca.Clear();
                ca.Add(Color.Black);
                ca.Add(Color.White);
                ca.Add(Color.Black);
                ca.Add(Color.White);
                imagedata = bg.create_image_four_quadrant_square_texture(ca, line_width);
                outputBuffer.Add(new PrepareImageData("", "VLine2", imagedata));
            }

            #endregion


            #region All RGB Color in one image

            if (checkBox_All_RGB.Checked)
            {
                Bitmap original = (Bitmap)Properties.Resources.all_rgb_color_in_one_image;
                Bitmap imagedata = new Bitmap(original, new Size(resX, resY));
                outputBuffer.Add(new PrepareImageData("", "AllRGB", imagedata));
            }

            #endregion

            #endregion

            #region Flicker
            if (checkBox_Flicker_Pattern.Checked)
            {
                Console.WriteLine("checkBox_Flicker_Pattern.Checked");

                Color co;
                Color ce;
                getFlickerPatternColor(out co, out ce);

                int patternSize = Convert.ToInt32(Math.Round(numericUpDown_Flicker.Value, 0));
                var imagedata = bg.createFlickerPattern(co, ce, patternSize);

                outputBuffer.Add(new PrepareImageData("", "Flicker_Pattern", imagedata));
            }

            if (checkBox_Flicker_HLine.Checked)
            {
                Console.WriteLine("checkBox_Flicker_HLine.Checked");

                Color co;
                Color ce;
                getFlickerPatternColor(out co, out ce);

                int patternSize = Convert.ToInt32(Math.Round(numericUpDown_Flicker.Value, 0));
                var imagedata = bg.createFlickerHLine(co, ce, patternSize);

                outputBuffer.Add(new PrepareImageData("", "Flicker_HLine", imagedata));
            }

            if (checkBox_Flicker_VLine.Checked)
            {
                Console.WriteLine("checkBox_Flicker_VLine.Checked");

                Color co;
                Color ce;
                getFlickerPatternColor(out co, out ce);

                int patternSize = Convert.ToInt32(Math.Round(numericUpDown_Flicker.Value, 0));
                var imagedata = bg.createFlickerVLine(co, ce, patternSize);

                outputBuffer.Add(new PrepareImageData("", "Flicker_VLine", imagedata));
            }
            #endregion

            #region Cross Talk
            if (checkBox_HVCrossTalk.Checked)
            {
                Bitmap imagedata = new Bitmap(resX, resY);

                var sourcegra = Graphics.FromImage(imagedata);//存入画布

                sourcegra.Clear(Color.White);

                SolidBrush myBrush = new SolidBrush(Color.Black);
                
                sourcegra.FillRectangle(myBrush, new Rectangle(resX / 3, resY / 3, resX / 3, resY / 3));

                outputBuffer.Add(new PrepareImageData("", "HVCrossTalk", imagedata));
            }

            if (checkBox_HCrossTalk.Checked)
            {
                Bitmap imagedata = new Bitmap(resX, resY);

                var canvas = Graphics.FromImage(imagedata);//存入画布

                canvas.Clear(Color.White);

                SolidBrush myBrush = new SolidBrush(Color.Black);

                canvas.FillRectangle(myBrush, new Rectangle(0, resY / 3, resX / 3, resY / 3));
                canvas.FillRectangle(myBrush, new Rectangle(2* resX / 3, resY / 3, resX / 3, resY / 3));

                outputBuffer.Add(new PrepareImageData("", "H_CrossTalk", imagedata));
            }

            if (checkBox_VCrossTalk.Checked)
            {
                Bitmap imagedata = new Bitmap(resX, resY);

                var canvas = Graphics.FromImage(imagedata);//存入画布

                canvas.Clear(Color.White);

                SolidBrush myBrush = new SolidBrush(Color.Black);

                canvas.FillRectangle(myBrush, new Rectangle(resX / 3, 0, resX / 3, resY / 3));
                canvas.FillRectangle(myBrush, new Rectangle(resX / 3, 2* resY / 3, resX / 3, resY / 3));

                outputBuffer.Add(new PrepareImageData("", "V_CrossTalk", imagedata));
            }



            #endregion

            #region Gradient
            if (checkBox_Gradient.Checked)
            {
                Bitmap imagedata = new Bitmap(resX, resY);

                var sourcegra = Graphics.FromImage(imagedata);//存入画布

                sourcegra.Clear(Color.White);

                SolidBrush myBrush = new SolidBrush(Color.Black);

                System.Drawing.Drawing2D.LinearGradientBrush lgb = new System.Drawing.Drawing2D.LinearGradientBrush(new Point(0, 0), new Point(resX, 0), colorGradientStart, colorGradientStop); ;

                if(radioButton_GD_LR.Checked == true)
                {
                    lgb = new System.Drawing.Drawing2D.LinearGradientBrush(new Point(0, 0), new Point(resX, 0), colorGradientStart, colorGradientStop);
                }

                if (radioButton_GD_RL.Checked == true)
                {
                    lgb = new System.Drawing.Drawing2D.LinearGradientBrush(new Point(resX, 0), new Point(0, 0), colorGradientStart, colorGradientStop);
                }

                if (radioButton_GD_UD.Checked == true)
                {
                    lgb = new System.Drawing.Drawing2D.LinearGradientBrush(new Point(0, 0), new Point(0, resY), colorGradientStart, colorGradientStop);
                }

                if (radioButton_GD_DU.Checked == true)
                {
                    lgb = new System.Drawing.Drawing2D.LinearGradientBrush(new Point(0, resY), new Point(0, 0), colorGradientStart, colorGradientStop);
                }

                if (radioButton_GD_LU_RD.Checked == true)
                {
                    lgb = new System.Drawing.Drawing2D.LinearGradientBrush(new Point(0, 0), new Point(resX, resY), colorGradientStart, colorGradientStop);
                }

                if (radioButton_GD_RD_LU.Checked == true)
                {
                    lgb = new System.Drawing.Drawing2D.LinearGradientBrush(new Point(resX, resY), new Point(0, 0), colorGradientStart, colorGradientStop);
                }

                if (radioButton_GD_RU_LD.Checked == true)
                {
                    lgb = new System.Drawing.Drawing2D.LinearGradientBrush(new Point(resX, 0), new Point(0, resY), colorGradientStart, colorGradientStop);
                }

                if (radioButton_GD_LD_RU.Checked == true)
                {
                    lgb = new System.Drawing.Drawing2D.LinearGradientBrush(new Point(0, resY), new Point(resX, 0), colorGradientStart, colorGradientStop);
                }

                sourcegra.FillRectangle(lgb, 0, 0, resX, resY);

                outputBuffer.Add(new PrepareImageData("", "Gradient", imagedata));
            }
            #endregion

            #endregion 根据checkbox填充outputbuffer

            #region 处理切割屏
            if (checkBox_isCutPanel.Checked == true)
            {
                for(int i = 0; i < outputBuffer.Count; i++)
                {
                    Image img = outputBuffer[i].bitmap;
                    Image imgNew = GetThumbnail(img, resX, keepY);

                    Bitmap bitmap = bg.createColorImage(Color.Black);
                    var sourcegra = Graphics.FromImage(bitmap);//存入画布
                    sourcegra.DrawImage(imgNew, 0, resY - keepY);

                    outputBuffer[i].bitmap = bitmap;
                }
            }
            #endregion

            #region Batch Output 
            Console.WriteLine("output buffer count: " + outputBuffer.Count.ToString());
            for (int i = 0; i < outputBuffer.Count; i++)
            {
                saveImage(outputBuffer[i].bitmap, outpuFolder, outputBuffer[i].subFolder, outputBuffer[i].fileName, imageFormat);
            }

            #endregion

            #region            输出log
            writeLog();
            #endregion

            #region 完成, 询问是否打开输出文件夹
            DialogResult dr = MessageBox.Show("是否打开输出文件夹", "提示", MessageBoxButtons.OKCancel);
            if (dr == DialogResult.OK)
            {
                try
                {
                    System.Diagnostics.Process.Start(outpuFolder);

                }
                catch
                {
                    MessageBox.Show("存储位置未设置！");
                }
            }
            else if (dr == DialogResult.Cancel)
            {
                //MessageBox.Show("您选择的是【取消】");
            }
            #endregion
        }

        private void writeLog()
        {
            string logName = "TPG_LOG_" + stringGenTime + ".txt";
            string fullLogName = Path.Combine(outpuFolder, logName);

            FileStream fs = new FileStream(fullLogName, FileMode.Create);
            StreamWriter sw = new StreamWriter(fs);
            
            // Title
            sw.WriteLine("TestPictureGenerator Log");

            string resInfo = string.Format("Resolution: \n\tWidth = {0} \n\tHeight = {1} \n\tCutKeep = {2}", resX, resY, keepY);
            sw.WriteLine(resInfo);
            sw.WriteLine("Files Output:");

            for (int i = 0; i < outputBuffer.Count; i++)
            {
                string fn = string.Format("\t{0}{1}", outputBuffer[i].fileName, imageFormat);
                sw.WriteLine(fn);
            }

            sw.WriteLine("Total:"+outputBuffer.Count.ToString());

            //清空缓冲区
            sw.Flush();
            //关闭流
            sw.Close();
            fs.Close();
        }

        private void button_allTestSwitch_Click(object sender, EventArgs e)
        {
            groupSelectMode += 1;

            if(groupSelectMode >= 4)
            {
                groupSelectMode = 0;
            }

            switch (groupSelectMode)
            {
                case 0:
                    checkBox_Frame.Checked = false;
                    checkBox_White.Checked = false;
                    checkBox_Red.Checked = false;
                    checkBox_Green.Checked = false;
                    checkBox_Blue.Checked = false;
                    checkBox_Black.Checked = false;
                    checkBox_Gray.Checked = false;
                    checkBox_ColorBar.Checked = false;
                    checkBox_Pic.Checked = false;

                    checkBox_SimpleFrame.Checked = false;
                    checkBox_SimpleWhite.Checked = false;
                    checkBox_SimpleColorBar.Checked = false;
                    checkBox_SimpleGray.Checked = false;
                    break;
                case 1:
                    checkBox_Frame.Checked = false;
                    checkBox_White.Checked = false;
                    checkBox_Red.Checked = false;
                    checkBox_Green.Checked = false;
                    checkBox_Blue.Checked = false;
                    checkBox_Black.Checked = false;
                    checkBox_Gray.Checked = false;
                    checkBox_ColorBar.Checked = false;
                    checkBox_Pic.Checked = false;

                    checkBox_SimpleFrame.Checked = true;
                    checkBox_SimpleWhite.Checked = true;
                    checkBox_SimpleColorBar.Checked = true;
                    checkBox_SimpleGray.Checked = true;
                    break;
                case 2:
                    checkBox_Frame.Checked = true;
                    checkBox_White.Checked = true;
                    checkBox_Red.Checked = true;
                    checkBox_Green.Checked = true;
                    checkBox_Blue.Checked = true;
                    checkBox_Black.Checked = true;
                    checkBox_Gray.Checked = true;
                    checkBox_ColorBar.Checked = true;
                    checkBox_Pic.Checked = true;

                    checkBox_SimpleFrame.Checked = false;
                    checkBox_SimpleWhite.Checked = false;
                    checkBox_SimpleColorBar.Checked = false;
                    checkBox_SimpleGray.Checked = false;
                    break;
                case 3:
                    checkBox_Frame.Checked = true;
                    checkBox_White.Checked = true;
                    checkBox_Red.Checked = true;
                    checkBox_Green.Checked = true;
                    checkBox_Blue.Checked = true;
                    checkBox_Black.Checked = true;
                    checkBox_Gray.Checked = true;
                    checkBox_ColorBar.Checked = true;
                    checkBox_Pic.Checked = true;

                    checkBox_SimpleFrame.Checked = true;
                    checkBox_SimpleWhite.Checked = true;
                    checkBox_SimpleColorBar.Checked = true;
                    checkBox_SimpleGray.Checked = true;
                    break;
            }
        }

        private void numericUpDown_OR_ValueChanged(object sender, EventArgs e)
        {
            ChangeFlickerPattern();
        }

        private void numericUpDown_OG_ValueChanged(object sender, EventArgs e)
        {
            ChangeFlickerPattern();
        }

        private void numericUpDown_OB_ValueChanged(object sender, EventArgs e)
        {
            ChangeFlickerPattern();
        }

        private void numericUpDown_ER_ValueChanged(object sender, EventArgs e)
        {
            ChangeFlickerPattern();
        }

        private void numericUpDown_EG_ValueChanged(object sender, EventArgs e)
        {
            ChangeFlickerPattern();
        }

        private void numericUpDown_EB_ValueChanged(object sender, EventArgs e)
        {
            ChangeFlickerPattern();
        }

        private void comboBox_LCD_Resolution_YES_LCD_SelectedIndexChanged(object sender, EventArgs e)
        {
            numericUpDown_ResX.Value = ((LCD_Code)comboBox_LCD_Resolution_YES_LCD.SelectedItem).wh.w;
            numericUpDown_ResY.Value = ((LCD_Code)comboBox_LCD_Resolution_YES_LCD.SelectedItem).wh.h;
        }

        private void checkBox_Gradient_CheckedChanged(object sender, EventArgs e)
        {

            gradientEnable();
        }

        private void pictureBox_GradientStartColor_Click(object sender, EventArgs e)
        {
            var result = colorDialog1.ShowDialog();
            if(result == DialogResult.OK)
            {
                colorGradientStart = colorDialog1.Color;
                pictureBox_GradientStartColor.BackColor = colorGradientStart;
            }
        }

        private void pictureBox_GradientStopColor_Click(object sender, EventArgs e)
        {
            var result = colorDialog1.ShowDialog();
            if (result == DialogResult.OK)
            {
                colorGradientStop = colorDialog1.Color;
                pictureBox_GradientStopColor.BackColor = colorGradientStop;
            }
        }

        private void checkBox3_CheckedChanged(object sender, EventArgs e)
        {
            if(((CheckBox)sender).Checked == true)
            {
                numericUpDown_CutKeep.Enabled = true;
                if(numericUpDown_CutKeep.Value < 1)
                {
                    //numericUpDown_CutKeep.Value = int.Parse(textBox_ResY.Text);
                    numericUpDown_CutKeep.Value = resY;
                }
            } else
            {
                numericUpDown_CutKeep.Enabled = false;
            } 
        }

        private void numericUpDown_CutKeep_ValueChanged(object sender, EventArgs e)
        {
            keepY = Convert.ToInt32(Math.Round(numericUpDown_CutKeep.Value, 0));
        }

        private void numericUpDown_ResX_ValueChanged(object sender, EventArgs e)
        {
            resX = Convert.ToInt32(Math.Round(numericUpDown_ResX.Value, 0));
            numericUpDown_HACT.Value = numericUpDown_ResX.Value;
        }

        private void numericUpDown_ResY_ValueChanged(object sender, EventArgs e)
        {
            resY = Convert.ToInt32(Math.Round(numericUpDown_ResY.Value, 0));
            numericUpDown_VACT.Value = numericUpDown_ResY.Value;
        }

        private void button_SwitchXY_Click(object sender, EventArgs e)
        {
            decimal temp = numericUpDown_ResX.Value;
            numericUpDown_ResX.Value = numericUpDown_ResY.Value;
            numericUpDown_ResY.Value = temp;
        }

        private void tabPage_Timming_Click(object sender, EventArgs e)
        {

        }

        private void numericUpDown_HACT_ValueChanged(object sender, EventArgs e)
        {

        }

        private void numericUpDown_HBP_ValueChanged(object sender, EventArgs e)
        {

        }

        private void numericUpDown_HSW_ValueChanged(object sender, EventArgs e)
        {

        }

        private void numericUpDown_HFP_ValueChanged(object sender, EventArgs e)
        {

        }

        private void numericUpDown_VFP_ValueChanged(object sender, EventArgs e)
        {

        }

        private void numericUpDown_VACT_ValueChanged(object sender, EventArgs e)
        {

        }

        private void numericUpDown_VBP_ValueChanged(object sender, EventArgs e)
        {

        }

        private void numericUpDown_VSW_ValueChanged(object sender, EventArgs e)
        {

        }

        private void timer_TimmingGetResolution_Tick(object sender, EventArgs e)
        {

        }

        private void button_CalculatePixelClock_Click(object sender, EventArgs e)
        {
            int fps = Convert.ToInt32(Math.Round(numericUpDown_FPS.Value, 0));
            numericUpDown_CLK.Value = DPI_Timming.getClockFromFps(dpitm, fps);
        }

        private void button_CalculateDsiBitrate_Click(object sender, EventArgs e)
        {
            int lane = Convert.ToInt32(Math.Round(numericUpDown_DsiLaneNum.Value, 0));
            int colorbits = int.Parse(comboBox_DsiColorFormat.Text);
            int bitrate = Convert.ToInt32(Math.Round(numericUpDown_CLK.Value)) * colorbits / lane;
            numericUpDown_DsiBitrate.Value = bitrate;
        }

        private void checkBox5_CheckedChanged(object sender, EventArgs e)
        {

        }

        private void checkBox4_CheckedChanged(object sender, EventArgs e)
        {
            
        }

        private void checkBox_DsiEnableChanged(object sender, EventArgs e)
        {
            if(checkBox_DsiEnable.Checked == true)
            {
                numericUpDown_DsiLaneNum.Enabled = true;
                comboBox_DsiColorFormat.Enabled = true;
                button_CalculateDsiBitrate.Enabled = true;
                numericUpDown_DsiBitrate.Enabled = true;
            } else
            {
                numericUpDown_DsiLaneNum.Enabled = false;
                comboBox_DsiColorFormat.Enabled = false;
                button_CalculateDsiBitrate.Enabled = false;
                numericUpDown_DsiBitrate.Enabled = false;
            }
        }

        private void button_gen_dpi_lua_Click(object sender, EventArgs e)
        {
            TextCopyForm tcf = new TextCopyForm();
            tcf.Show();

            string str;

            str = string.Format("HA={0}\r", numericUpDown_HACT.Value.ToString());
            tcf.richTextBox_script_string.AppendText(str);

            str = string.Format("HSW={0}\r", numericUpDown_HSW.Value.ToString());
            tcf.richTextBox_script_string.AppendText(str);

            str = string.Format("HBP={0}\r", numericUpDown_HBP.Value.ToString());
            tcf.richTextBox_script_string.AppendText(str);

            str = string.Format("HFP={0}\r", numericUpDown_HFP.Value.ToString());
            tcf.richTextBox_script_string.AppendText(str);

            str = string.Format("VA={0}\r", numericUpDown_VACT.Value.ToString());
            tcf.richTextBox_script_string.AppendText(str);

            str = string.Format("VSW={0}\r", numericUpDown_VSW.Value.ToString());
            tcf.richTextBox_script_string.AppendText(str);

            str = string.Format("VBP={0}\r", numericUpDown_VBP.Value.ToString());
            tcf.richTextBox_script_string.AppendText(str);

            str = string.Format("VFP={0}\r", numericUpDown_VFP.Value.ToString());
            tcf.richTextBox_script_string.AppendText(str);

            str = string.Format("FPS={0}\r", numericUpDown_FPS.Value.ToString());
            tcf.richTextBox_script_string.AppendText(str);

            if(comboBox_PolHs.SelectedIndex == 0)
            {
                str = string.Format("HSYNC_POL=0  --0:LOW-ACT 1:HIGH-ACT\r");
            } else
            {
                str = string.Format("HSYNC_POL=1  --0:LOW-ACT 1:HIGH-ACT\r");
            }   
            tcf.richTextBox_script_string.AppendText(str);

            if (comboBox_PolVs.SelectedIndex == 0)
            {
                str = string.Format("VSYNC_POL=0  --0:LOW-ACT 1:HIGH-ACT\r");
            }
            else
            {
                str = string.Format("VSYNC_POL=1  --0:LOW-ACT 1:HIGH-ACT\r");
            }
            tcf.richTextBox_script_string.AppendText(str);

            if (comboBox_PolDe.SelectedIndex == 0)
            {
                str = string.Format("DE_POL=0  --0:LOW-ACT 1:HIGH-ACT\r");
            }
            else
            {
                str = string.Format("DE_POL=1  --0:LOW-ACT 1:HIGH-ACT\r");
            }
            tcf.richTextBox_script_string.AppendText(str);

            if (comboBox_PolClk.SelectedIndex == 0)
            {
                str = string.Format("CLK_POL=0   --0:RISING-EDGE-LATCH 1:FALLING-EDGE-LATCH\r");
            }
            else
            {
                str = string.Format("CLK_POL=1   --0:RISING-EDGE-LATCH 1:FALLING-EDGE-LATCH\r");
            }
            tcf.richTextBox_script_string.AppendText(str);

            str = string.Format("t10_DPI(HA,HSW,HBP,HFP,VA,VSW,VBP,VFP, HSYNC_POL,VSYNC_POL,DE_POL,CLK_POL, FPS)");
            tcf.richTextBox_script_string.AppendText(str);

            //tcf.richTextBox_script_string.Text = str;
        }
    }
}
